#ifndef __TRIPLE__
#define __TRIPLE__

#include <iostream>
using namespace std;

#define X 0
#define Y 1
#define Z 2

#include "processor.h"

// If a class is overriding a virtual method, then the first 4 octets in every instance are occupied by the VMT pointer

class Matrix;

#define FP_DATATYPE float
//#define FP_DATATYPE double

// A triple object is conceptually an array of 3 float numbers (single precision).
class Triple
{
private:
	__declspec(align(16)) FP_DATATYPE coord[
#ifdef SSSE3
	4 // XMM register size
#else
	3
#endif
	];
	void *base_ptr; // original pointer obtained with standard memory allocation; delete this pointer in destructor
public:
    Triple(); // coord = xmm0
    Triple(FP_DATATYPE *src); // coord = src
	FP_DATATYPE& operator[](const int index)
	{
	    return coord[index];
	}
	void* operator new(size_t);
	void operator delete(void* m);
	void ToHTMLString(ostream& os, char *title);
	void Set(float x, float y, float z);
	void Reset();
	void operator=(const Triple& src);
	Triple operator-()
	{
		Triple result;
		result[X] = -this->coord[X];
		result[Y] = -this->coord[Y];
		result[Z] = -this->coord[Z];
		return result;
	}
    friend const Triple operator+(Triple& left, Triple& right);
	const void operator+=(Triple& right);
	friend const Triple operator-(Triple& left, Triple& right);
	void Substract(Triple &a); // this -= a
	friend const Triple operator*(Triple& left, Triple& right);
	friend const Triple operator*(Triple& left, const FP_DATATYPE right);
	void Multiply(Matrix& m, Triple& t);
	friend const Triple operator/(Triple& left, Triple& right);
	friend const Triple operator/(Triple& left, const FP_DATATYPE right);
	void Integrate(Triple& derivative, const FP_DATATYPE dt);
	FP_DATATYPE DotProduct();
	FP_DATATYPE DotProduct(Triple& a);
	void CrossProduct(Triple& a, Triple& b); // xyzzy rule
	void SquareDistance(Triple& a, Triple& b);
	void Project(Triple& f, Triple& support); // projection = this
	void Normalize();
};

#endif
